<template>
    <div>
        <el-form label-width="110px" size="small">
            <el-row class="form-row">
                <el-col :span="12">
                    <el-form-item label="产品代码:">
                        <RiskEntryInput id="fundCode" @set-entry-data="getEntryslist" :returnDatas="instruction.fundCode" />
                    </el-form-item>
                    <el-form-item label="资产单元编号:" v-show="SHOW_SECURITY">
                        <el-select v-model="instruction.assetCode" size="mini">
                            <el-option
                                v-for="i in computedAssetCodeSelectData"
                                :key="i.assetCode"
                                :label="i.assetCode + ' ' + i.assetName"
                                :value="i.assetCode"
                            >
                            </el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="组合编码:">
                        <el-select name="组合编码" v-model="instruction.fundAccountCode" size="mini">
                            <el-option
                                v-for="i in computedFundAccountCodeSelectData"
                                :key="i.fundAccountCode"
                                :label="i.fundAccountCode + ' ' + i.fundAccountName"
                                :value="i.fundAccountCode"
                            >
                            </el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="合约代码:">
                        <el-select
                            name="合约代码"
                            v-model="instruction.stockCode"
                            filterable
                            :filter-method="getStockCodeList"
                            :loading="selectLoading"
                            @change="handleStockCodeChange"
                            @visible-change="handleStockVisibleChange"
                            size="mini"
                            clearable
                            @clear="getStockCodeList('')"
                        >
                            <el-option
                                v-for="i in stockCodeSelectData"
                                :key="i.stockCode"
                                :label="i.stockCode + ' ' + i.stockNameSt"
                                :value="i.stockCode"
                                :name="'stockCode' + i.stockCode"
                            >
                            </el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="业务类型:">
                        <el-select name="业务类型" v-model="instruction.businessType" size="mini">
                            <el-option v-for="i in businessTypeData" :key="i.value" :label="i.label" :value="i.value"> </el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="委托方向:">
                        <el-select
                            name="委托方向"
                            v-model="instruction.orderDirection"
                            size="mini"
                            :class="['font-color-' + textColor]"
                            @change="handleOrderDirectionChange"
                        >
                            <el-option
                                v-for="i in orderDirectionSelectData"
                                :key="i.dictKey"
                                :label="i.dictKeyName"
                                :value="i.dictKey"
                                :style="handleTextColor(i.dictKey)"
                                :name="'orderDirection-' + i.dictKey"
                            >
                            </el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="投资类型:">
                        <el-select name="投资类型" v-model="instruction.investType" size="mini">
                            <el-option
                                v-for="i in investmentTypeData"
                                :key="i.value"
                                :label="i.label"
                                :value="i.value"
                                :name="'investType-' + i.value"
                            >
                            </el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="指令价格:">
                        <RiskInputNumber
                            name="orderPrice"
                            :input="instruction.orderPrice"
                            :inputAfter="'元'"
                            :colorStyle="textColor"
                            :precision="3"
                            :maxlength="15"
                            :field="'orderPrice'"
                            @getInputNumber="getInputNumber(arguments)"
                        >
                        </RiskInputNumber> </el-form-item
                    ><el-form-item label="指令数量:">
                        <RiskInputNumber
                            name="orderAmount"
                            :input="instruction.orderAmount"
                            :inputAfter="'手'"
                            :colorStyle="textColor"
                            :maxlength="15"
                            :precision="2"
                            :field="'orderAmount'"
                            :readonly="!instruction.stockCode"
                            @getInputNumber="getInputNumber(arguments)"
                        >
                        </RiskInputNumber>
                    </el-form-item>
                    <el-form-item label="合约价值:">
                        <RiskInputNumber
                            name="orderBalances"
                            :input="orderBalances"
                            :inputAfter="'元'"
                            :colorStyle="textColor"
                            :precision="2"
                            :maxlength="15"
                            :field="'orderBalances'"
                            :disabled="true"
                            @getInputNumber="getInputNumber(arguments)"
                        >
                        </RiskInputNumber>
                    </el-form-item>
                    <el-form-item label="目标类型:">
                        <el-select name="目标类型" v-model="instruction.targetType" size="mini" disabled>
                            <el-option v-for="(value, key) in targetTypePojo" :key="key" :label="value" :value="key"> </el-option>
                        </el-select>
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
    </div>
</template>

<script lang="ts">
import Invest from '@/common/dict/invest';
import DictionConstUtil, { objToArr, SGU_CACHE } from '@/utils/diction-const-util';
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import { FuturesOrderType } from '../types/FuturesOrderType';
import { getBusinessType, getFutureContractMulti } from '../api';
import { NumberToWords, highlightColor, handleTextColor, handleLimitAmount, uniqueFunc, getConfigItem } from '@/utils/tools';
import RiskInputNumber from '@/pages/risk-measure/components/risk-input-number.vue';
import { Dictionary } from '@/pages/risk-time/types/Dictionary';
import { SelectOptionItemData } from '@/pages/risk-time/types/SelectOptionItemData';
import RiskEntryInput from '@/common/components/risk-entry-input.vue';

@Component({
    name: 'FuturesOrder',
    components: {
        RiskInputNumber,
        RiskEntryInput,
    },
})

// 期货指令
export default class FuturesOrder extends Vue {
    @Prop()
    detail: any;
    @Prop()
    stockInfoCache: any;
    @Prop()
    notMesh: boolean;

    Invest: any = new Invest();
    handleTextColor = handleTextColor;
    selectLoading: boolean = false; // 下拉框远程搜索时的加载状态
    fundCodeSelectData: any[] = []; // 产品序号下拉框数据
    fundAccountCodeSelectData: any[] = []; // 组合编码下拉框数据
    allStockType: any[] = [];
    allOrderDirection: any[] = [];
    orderDirectionSelectData: any[] = []; // 订单方向下拉框数据
    investTypeSelectData: any[] = []; // 投资类型下拉框数据
    stockCodeSelectData: any[] = []; // 证券代码下拉框数据
    contractMulti: string = ''; // 合约乘数
    stockReport: any[] = [];
    textColor: string = ''; // 红绿凸显

    instruction = {
        fundCode: '', // 产品代码
        fundAccountCode: '', // 组合编码
        reportCode: '', // 申报代码
        orderDirection: '', // 委托方向
        businessType: '4',
        orderPrice: '', // 指令价格
        orderAmount: '', // 指令数量
        orderBalance: '', // 合约价值
        orderBalances: '', // 展示合约价值
        investType: 'b', // 投资类型
        fundNameSt: '',
        fundAccountName: '',
        assetCode: '',
        assetName: '',
        stockCode: '',
        targetType: '1',
    };
    orderBalances: string = ''; // 展示合约价值
    businessTypeData: SelectOptionItemData[] = [];
    // 业务类型
    defaultBusinessTypeData: SelectOptionItemData[] = [
        {
            label: '期货业务',
            value: '4',
        },
    ];

    // 投资类型
    private investmentTypeData = [
        {
            label: '投机',
            value: 'a',
        },
        {
            label: '套保',
            value: 'b',
        },
        {
            label: '套利',
            value: 'c',
        },
    ];
    stockInfo: any = {};
    targetTypePojo: any = {}; // 目标类型
    changeFlag: string = ''; // 证券变动方向
    hasRatio: boolean = true; // 是否有期货保证金比例

    async mounted() {
        // 获取产品信息 (产品序号下拉框数据)
        this.fundCodeSelectData = await SGU_CACHE('FundInfo', '/fundInfo/list', []);
        // 获取组合编码下拉框数据
        let arr = await SGU_CACHE('FundAccount', '/fundInfo/accounts', []);
        arr.forEach(item => {
            this.fundAccountCodeSelectData[item.fundCode] = item.fundAccounts;
        });
        // 获取投资类型下拉框数据
        this.investTypeSelectData = objToArr(this.Invest.investType);
        // 获取证券代码下拉框数据
        this.getStockCodeList('');
        // 获取所有证券类别 (用于筛选订单方向)
        this.allStockType = await SGU_CACHE('StockType', '/dict/stockType/list', []);
        // 获取所有订单方向
        this.allOrderDirection = await SGU_CACHE('TradeDirection', '/dict/tradeDirections', []);
        this.businessTypeData = this.defaultBusinessTypeData;
        // 获取目标类型
        this.targetTypePojo = DictionConstUtil.targetType;
    }

    @Watch('instruction', { immediate: true, deep: true })
    setValues() {
        this.$emit('handleSettingValue', this.instruction, '7');
    }

    @Watch('stockInfoCache', { immediate: true, deep: true })
    onWatchStockInfo() {
        if (this.stockInfoCache) {
            this.stockInfo = this.stockInfoCache;
            // this.orderDirectionSelectData = this.stockInfoCache.tradeDirections;
            this.getStockCodeList(this.stockInfo.reportCode);
        }
    }

    @Watch('detail', { immediate: true, deep: true })
    async setForm() {
        if (this.detail && Object.keys(this.detail).length) {
            let instruction = this.detail;
            // 获取组合编码下拉框数据
            let arr = await SGU_CACHE('FundAccount', '/fundInfo/accounts', []);
            arr.forEach(item => {
                this.fundAccountCodeSelectData[item.fundCode] = item.fundAccounts;
            });
            for (const key in this.instruction) {
                this.instruction[key] = instruction[key];
            }
            // 指令修改回显
            if (this.detail.instNo) {
                // 组合编码
                this.instruction.fundAccountCode = instruction.groupCode;
                // 组合名称
                this.instruction.fundAccountName = instruction.groupName;
            }
            this.instruction.targetType = '1';
            await this.getStockCodeList(this.detail?.stockCode);
            this.stockInfo = this.stockCodeSelectData.find(item => item.stockCode === this.detail?.stockCode);
            this.instruction.reportCode = this.stockInfo?.reportCode;
            // this.orderDirectionSelectData = this.stockInfo?.tradeDirections;
            this.$emit('getStockInfo', this.stockInfo, '7');
            await this.getContractMulti(this.stockInfo?.stockCode);
            this.getCalOrderBalance();
            if (this.stockInfo?.marketCode && this.stockInfo?.stockType) {
                this.handleStockBusinessType(this.stockInfo.marketCode, this.stockInfo.stockType, false);
            }
        } else {
            this.stockInfo = {};
            this.getStockCodeList('');
        }
    }

    SHOW_SECURITY = getConfigItem('SHOW_SECURITY');
    // 监听 资产单元计算属性 (每当计算属性变动时 自动选中第一项)
    @Watch('computedAssetCodeSelectData', { immediate: true, deep: true })
    watchcomputedAssetCode(newData) {
        if (!this.SHOW_SECURITY) {
            return;
        }
        let obj: any = {};
        if (newData && newData.length) {
            const d1 = newData.find(item => item.assetCode == this.instruction.assetCode);
            obj = d1 || newData[0];
        }
        this.instruction.assetCode = obj.assetCode;
        this.instruction.assetName = obj.assetName;
    }

    // 监听 组合编码计算属性 (每当计算属性变动时 自动选中第一项)
    @Watch('computedFundAccountCodeSelectData', { immediate: true, deep: true })
    watchcomputedFundAccountCode(newData) {
        let obj: any = {};
        if (newData && newData.length) {
            const d1 = newData.find(item => item.fundAccountCode == this.instruction.fundAccountCode);
            obj = d1 || newData[0];
        }
        this.instruction.assetCode = obj.assetCode;
        this.instruction.assetName = obj.assetName;
        this.instruction.fundAccountCode = obj.fundAccountCode;
        this.instruction.fundAccountName = obj.fundAccountName;
    }

    get computedAssetCodeSelectData(): any {
        return uniqueFunc(this.fundAccountCodeSelectData[this.instruction.fundCode], 'assetCode');
    }

    // 组合编码下拉框计算属性;
    get computedFundAccountCodeSelectData() {
        let data = this.fundAccountCodeSelectData[this.instruction.fundCode];
        let retData = [];
        if (data && this.SHOW_SECURITY) {
            const obj = data.filter(item => item.assetCode == this.instruction.assetCode);
            retData = obj || [];
        } else {
            retData = data;
        }
        return retData;
    }

    /**
     * 判断字段颜色
     */
    @Watch('instruction', { immediate: true, deep: true })
    handleFieldColor() {
        if (['X', 'V'].includes(this.instruction.orderDirection)) {
            this.textColor = highlightColor()[1];
        } else if (['Y', 'W'].includes(this.instruction.orderDirection)) {
            this.textColor = highlightColor()[2];
        } else {
            this.textColor = highlightColor()[0];
        }
    }

    getInputNumber(args: any) {
        let value = args[0];
        let field = args[1];
        if (field == 'orderBalances') {
            this[field] = value;
            this.instruction.orderBalances = value;
        } else {
            this.instruction[field] = value;
        }
        if (field === 'orderPrice' || field === 'orderAmount') {
            this.getCalOrderBalance();
        } else if (field === 'orderAmount') {
            // todo
            setTimeout(() => {
                this.handleOrderAmount(value);
            }, 10);
        }
    }

    /**
     * 查询期货保证金比例参数
     */
    async getFutureDepositRatio() {
        if (this.instruction.fundCode && this.instruction.stockCode) {
            await this.$axios
                .post('/stockInfo/getFuture/depositRatio?fundCode=' + this.instruction.fundCode + '&stockCode=' + this.instruction.stockCode)
                .then(res => {
                    if (res && JSON.stringify(res) !== '{}') {
                        this.hasRatio = true;
                    } else {
                        this.hasRatio = false;
                    }
                })
                .catch(() => {
                    this.hasRatio = false;
                });
            this.$emit('getFutureRatio', this.hasRatio);
        }
    }

    handleOrderDirectionChange(value) {
        let obj = this.orderDirectionSelectData.find(ele => ele.dictKey == value);
        if (obj) {
            this.changeFlag = obj.param2;
        } else {
            this.changeFlag = '';
        }
    }

    handleOrderAmount(value) {
        if (value) {
            // 限定指令数量
            let limit = handleLimitAmount(this.changeFlag, this.stockInfo, value);
            if (!limit) {
                this.instruction.orderAmount = '';
            }
        }
        this.getCalOrderBalance();
    }

    // 计算合约价值
    getCalOrderBalance() {
        this.orderBalances = (
            Number(this.instruction.orderPrice || 0) *
            Number(this.instruction.orderAmount || 0) *
            Number(this.contractMulti || 0)
        ).toString();
        this.instruction.orderBalances = this.orderBalances;
        this.instruction.orderBalance = (Number(this.instruction.orderPrice || 0) * Number(this.instruction.orderAmount || 0)).toString();
    }

    getEntryslist(val: any) {
        this.instruction.fundCode = val;
        this.handleFundCodeChange(val);
    }

    async handleFundCodeChange(value: string) {
        let fund = this.fundCodeSelectData.find(item => item.fundCode === value) || {};
        let fundAccount = (this.fundAccountCodeSelectData[this.instruction.fundCode] || [])[0] || {};
        this.instruction.fundNameSt = fund.fundNameSt;
        this.instruction.fundAccountCode = fundAccount.fundAccountCode;
        this.instruction.fundAccountName = fundAccount.fundAccountName;
        this.instruction.assetCode = fundAccount.assetCode;
        this.instruction.assetName = fundAccount.assetName;
        await this.getFutureDepositRatio();
    }

    handleFundAccountCodeChange(value: string) {
        let fundAccount = (this.fundAccountCodeSelectData[this.instruction.fundCode] || []).find(item => item.fundAccountCode === value) || {};
        this.instruction.fundAccountName = fundAccount.fundAccountName;
        this.instruction.assetCode = fundAccount.assetCode;
        this.instruction.assetName = fundAccount.assetName;
    }

    // 获取证券代码下拉框数据
    async getStockCodeList(val: string) {
        this.selectLoading = true;
        await this.$axios
            .post('/dict/stock/report/select/' + 2 + '/v1', {
                dictKey: val,
                dictKeyName: val,
            })
            .then((res: any) => {
                this.stockCodeSelectData = res || [];
                this.selectLoading = false;
            });
    }

    handleStockCodeChange(value: string): void {
        this.instruction.orderDirection = '';
        if (value) {
            this.stockInfo = this.stockCodeSelectData.find(item => item.stockCode === value);
            // this.orderDirectionSelectData = this.stockInfo?.tradeDirections;
            this.instruction.reportCode = this.stockInfo?.reportCode;
            this.$emit('getStockInfo', this.stockInfo, '7');
            this.getContractMulti(this.stockInfo?.stockCode);

            if (this.stockInfo.marketCode && this.stockInfo.stockType) {
                this.handleStockBusinessType(this.stockInfo.marketCode, this.stockInfo.stockType, true);
            }
        } else {
            this.instruction.reportCode = '';
            this.orderDirectionSelectData = [];
        }
        this.instruction.orderAmount = '';
        this.instruction.orderPrice = '';
        this.instruction.orderBalance = '';
        this.orderBalances = '';
        this.instruction.orderBalances = this.orderBalances;
        this.getFutureDepositRatio();
    }

    handleStockVisibleChange(val) {
        if (!val) {
            this.getStockCodeList(this.instruction.stockCode);
        }
    }

    /**
     * reset: 是否设置委托方向为默认第一个
     */
    async handleStockBusinessType(marketCode, stockType, reset) {
        let res = await getBusinessType(marketCode, stockType);
        if (res && res.length > 0) {
            this.businessTypeData = res.map(
                item =>
                    ({
                        label: item.dictKeyName,
                        value: item.dictKey,
                    } as SelectOptionItemData)
            );
            let innerOrderDirectionData = res;
            innerOrderDirectionData.filter(ele => {
                if (ele.dictKey == this.instruction.businessType) {
                    if (ele['innerDictionary'] && JSON.stringify(ele['innerDictionary']) !== '{}') {
                        this.orderDirectionSelectData = JSON.parse(ele['innerDictionary'] || '[]');
                    } else {
                        this.orderDirectionSelectData = [];
                        this.instruction.orderDirection = '';
                    }
                    if (this.orderDirectionSelectData.length && reset) {
                        this.instruction.orderDirection = this.orderDirectionSelectData[0].dictKey;
                        this.changeFlag = this.orderDirectionSelectData[0].param2;
                    } else {
                        if (reset) {
                            this.yh_message_warn('该业务类型无对应的委托方向');
                        }
                    }
                }
            });
        } else {
            this.businessTypeData = this.defaultBusinessTypeData;
        }
    }

    /**
     * 获取合约乘数
     */
    async getContractMulti(stockCode) {
        if (stockCode) {
            let contractMulti = await getFutureContractMulti(stockCode);
            if (!contractMulti) {
                contractMulti = 0;
            } else {
                this.contractMulti = contractMulti;
            }
            this.$emit('getContractMulti', this.contractMulti);
        }
    }
}
</script>
<style lang="scss" scoped>
@import '@/pages/risk-measure/style/measure';
@import '@/pages/risk-time/styles/order-form';
</style>
